/*
 * @(#)ServiceLocator.java 1.0 2005-2-26
 * Copyright 2005 VandaGroup, Inc. All rights reserved.
 */
package com.vanda.util;

import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.sql.DataSource;

/*******************************************************************************
 * 类说明: 通用资源访问对象（单例模式）
 * <P>
 * 
 * @author 蒋勇
 *         <P>
 * @version 1.0 2005-2-26
 */
public class ServiceLocator {
	static {
		try {
			_instance = new ServiceLocator();
		} catch (NamingException se) {
			se.printStackTrace();
		}
	}

	private static ServiceLocator _instance;

	static public ServiceLocator getInstance() {
		return _instance;
	}

	private Map cache;

	private InitialContext initialContext;

	private ServiceLocator() throws NamingException {
		initialContext = new InitialContext();
		cache = Collections.synchronizedMap(new HashMap());
	}

	/*public Object getEJBHome(String jndiHomeName) throws NamingException {
		if (cache.containsKey(jndiHomeName)) {
			return cache.get(jndiHomeName);
		} else {

			if (initialContext != null) {
				Object nsObject = initialContext.lookup(jndiHomeName);

				if (nsObject instanceof EJBLocalHome) {
					cache.put(jndiHomeName, nsObject);
					return nsObject;
				} else {
					if (nsObject instanceof org.omg.CORBA.Object) {
						EJBHome ejbHome = (EJBHome) javax.rmi.PortableRemoteObject
								.narrow((org.omg.CORBA.Object) nsObject,
										EJBHome.class);
						cache.put(jndiHomeName, ejbHome);
						return ejbHome;
					} else {
						cache.put(jndiHomeName, nsObject);
						return nsObject;
					}

				}
			} else {
				throw new NamingException("ServiceLocator:no InitialContext");
			}
		}
	}*/

	public java.lang.Object getEJBHome(String jndiHomeName)
			throws NamingException,RemoteException {
		if (cache.containsKey(jndiHomeName)) 
			return cache.get(jndiHomeName);
		
		if (initialContext != null) {
			java.lang.Object nsObject = initialContext.lookup(jndiHomeName);
			Class homeClass = null;

			if (nsObject instanceof EJBHome) {
				homeClass = ((EJBHome) nsObject).getEJBMetaData()
						.getHomeInterfaceClass();
				EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(
						(org.omg.CORBA.Object) nsObject, homeClass);
				cache.put(jndiHomeName, ejbHome);
				return ejbHome;
			} else {
				if (nsObject instanceof org.omg.CORBA.Object) {
					homeClass = ((EJBHome) PortableRemoteObject.narrow(
							(org.omg.CORBA.Object) nsObject, EJBHome.class))
							.getEJBMetaData().getHomeInterfaceClass();
					EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(
							(org.omg.CORBA.Object) nsObject, homeClass);
					cache.put(jndiHomeName, ejbHome);
					return ejbHome;
				}else{
					cache.put(jndiHomeName, nsObject);
					return nsObject;
				}
			}
		} else {
			throw new NamingException("ServiceLocator:no InitialContext");
		}
		
	}

	/**
	 * 通过Local接口取得ejb实例
	 * 
	 * @param jndiHomeName
	 * @return
	 */
	public EJBLocalObject createLocal(String jndiHomeName) throws Exception {
		EJBLocalHome home = (EJBLocalHome) getEJBHome(jndiHomeName);
		Method method = home.getClass().getMethod("create", null);
		EJBLocalObject obj = (EJBLocalObject) method.invoke(home, null);
		return obj;
	}

	/**
	 * 取得ejb实例
	 * 
	 * @param jndiHomeName
	 * @return
	 */
	public EJBObject create(String jndiHomeName) throws Exception {

		EJBHome home = (EJBHome) getEJBHome(jndiHomeName);

		Method method = home.getClass().getMethod("create", null);

		EJBObject obj = (EJBObject) method.invoke(home, null);

		return obj;
	}

	public DataSource getDataSource(String dataSourceName)
			throws NamingException {
		DataSource dataSource = null;
		if (cache.containsKey(dataSourceName)) {
			dataSource = (DataSource) cache.get(dataSourceName);
		} else {
			dataSource = (DataSource) initialContext.lookup(dataSourceName);
			cache.put(dataSourceName, dataSource);
		}
		return dataSource;
	}
}